import axios from 'axios'
import { ElNotification, ElMessageBox } from 'element-plus'
import projectSetting from '@/settings/projectSetting'
import sysCache from '@/utils/cache'
import router from '@/router'

axios.defaults.baseURL = process.env.VUE_APP_API_URL

axios.defaults.timeout = projectSetting.TIMEOUT

// HTTP request 拦截器
axios.interceptors.request.use(
  (config: any) => {
    // 获取token
    const token = sysCache.localCache.getCache('TOKEN')
    if (token) {
      config.headers[projectSetting.TOKEN_NAME] = token
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// HTTP response 拦截器
axios.interceptors.response.use(
  (response) => {
    return response
  },
  (error) => {
    if (error.response) {
      if (error.response.status == 404) {
        ElNotification.error({
          title: '请求错误',
          message: 'Status:404，正在请求不存在的服务器记录！'
        })
      } else if (error.response.status == 500) {
        ElNotification.error({
          title: '请求错误',
          message: error.response.data.message || 'Status:500，服务器发生错误！'
        })
      } else if (error.response.status == 401) {
        ElMessageBox.confirm(
          '当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。',
          '无权限访问',
          {
            type: 'error',
            closeOnClickModal: false,
            center: true,
            confirmButtonText: '重新登录'
          }
        )
          .then(() => {
            router.replace({ path: '/login' })
          })
          // eslint-disable-next-line @typescript-eslint/no-empty-function
          .catch(() => {})
      } else {
        ElNotification.error({
          title: '请求错误',
          message: error.response.data.message || `Status:${error.response.status}，未知错误！`
        })
      }
    } else {
      ElNotification.error({
        title: '请求错误',
        message: '请求服务器无响应！'
      })
    }

    return Promise.reject(error.response)
  }
)

const http = {
  /** get 请求
   * @param  {接口地址} url
   * @param  {请求参数} params
   * @param  {参数} config
   */
  get: function (url, params = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'get',
        url: url,
        params: params,
        ...config
      })
        .then((response) => {
          resolve(response.data)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },

  /** post 请求
   * @param  {接口地址} url
   * @param  {请求参数} data
   * @param  {参数} config
   */
  post: function (url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'post',
        url: url,
        data: data,
        ...config
      })
        .then((response) => {
          resolve(response.data)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },

  /** put 请求
   * @param  {接口地址} url
   * @param  {请求参数} data
   * @param  {参数} config
   */
  put: function (url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'put',
        url: url,
        data: data,
        ...config
      })
        .then((response) => {
          resolve(response.data)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },

  /** patch 请求
   * @param  {接口地址} url
   * @param  {请求参数} data
   * @param  {参数} config
   */
  patch: function (url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'patch',
        url: url,
        data: data,
        ...config
      })
        .then((response) => {
          resolve(response.data)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },

  /** delete 请求
   * @param  {接口地址} url
   * @param  {请求参数} data
   * @param  {参数} config
   */
  delete: function (url, data = {}, config = {}) {
    return new Promise((resolve, reject) => {
      axios({
        method: 'delete',
        url: url,
        data: data,
        ...config
      })
        .then((response) => {
          resolve(response.data)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },

  /** jsonp 请求
   * @param  {接口地址} url
   * @param  {JSONP回调函数名称} name
   */
  jsonp: function (url, name = 'jsonp') {
    return new Promise((resolve) => {
      const script = document.createElement('script')
      const _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
      script.id = _id
      script.type = 'text/javascript'
      script.src = url
      window[name] = (response) => {
        resolve(response)
        document.getElementsByTagName('head')[0].removeChild(script)
        try {
          delete window[name]
        } catch (e) {
          window[name] = undefined
        }
      }
      document.getElementsByTagName('head')[0].appendChild(script)
    })
  }
}

export default http
